home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / x11 / _x11.c next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  16.6 KB  |  704 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _x11.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. // basic graphic routines for libWx declared in <LEDA/impl/x_basic.h>
  17. // implemented using the X11 library functions (libX11)
  18.  
  19.  
  20. #include <LEDA/impl/x_basic.h>
  21.  
  22. #include <iostream.h>
  23.  
  24. #include <X11/X.h>
  25. #include <X11/Xlib.h>
  26. #include <X11/Xutil.h>
  27.  
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <stdlib.h>
  31. #include <math.h>
  32.  
  33. #include <LEDA/bitmaps/leda_icon.xbm>
  34.  
  35.  
  36. static char dot_mask[2] = { 1,4 };
  37. static char dash_mask[2] = { 4,4 };
  38.  
  39. static char* text_font_name = "screen16";
  40. static char* bold_font_name = "screen-bold16";
  41. static char* mesg_font_name = "10x20";
  42.  
  43. static char* text_font_name2 = "9x15";
  44. static char* bold_font_name2 = "9x15bold";
  45. static char* mesg_font_name2 = "lucidasans20";
  46.  
  47.  
  48.  
  49. static Display     *display = NULL;
  50. static int          screen;
  51. static XEvent       event;
  52. static XGCValues    gc_val;
  53. static GC           gc;
  54. static Colormap     color_map;
  55.  
  56. static XFontStruct *text_font;
  57. static XFontStruct *bold_font;
  58. static XFontStruct *mesg_font;
  59. static XFontStruct *current_font;
  60.  
  61. static int mesg_char_width;
  62. static int bold_char_width;
  63. static int text_char_width;
  64. static int current_char_width;
  65.  
  66. const  int MAX_COLORS = 256; 
  67. static unsigned long color_pix[MAX_COLORS];
  68. static char* color_name[MAX_COLORS];
  69. static int color_count= 0;
  70.  
  71. static int LINESTYLE = 0;
  72. static int MODE      = 0;
  73. static int COLOR     = 1;
  74.  
  75.  
  76. static int get_char_width(XFontStruct* fp)
  77. { XCharStruct char_struct;
  78.   int asc, desc, dir;
  79.   XQueryTextExtents(display,fp->fid,"H",1, &dir,&asc,&desc,&char_struct);
  80.   return char_struct.width;
  81. }
  82.  
  83.  
  84. void open_display(void)
  85.   if (display!=NULL) return;
  86.  
  87.   if ((display = XOpenDisplay(0)) == NULL)    
  88.   { fprintf(stderr, "Can\'t open display: \n");
  89.     abort();
  90.    }
  91.  
  92.   screen    = DefaultScreen(display);
  93.   color_map = DefaultColormap(display,screen);
  94.   gc        = DefaultGC(display,screen);
  95.  
  96.  
  97.   if ((text_font = XLoadQueryFont(display,text_font_name)) == NULL)
  98.   if ((text_font = XLoadQueryFont(display,text_font_name2)) == NULL)
  99.   { fprintf(stderr,"Error: Cannot load text font");
  100.     exit(1);
  101.    }
  102.  
  103.   if ((bold_font = XLoadQueryFont(display,bold_font_name)) == NULL)
  104.   if ((bold_font = XLoadQueryFont(display,bold_font_name2)) == NULL)
  105.   { fprintf(stderr,"Error: Cannot load bold font");
  106.     exit(1);
  107.    }
  108.  
  109.   if ((mesg_font = XLoadQueryFont(display,mesg_font_name)) == NULL)
  110.   if ((mesg_font = XLoadQueryFont(display,mesg_font_name2)) == NULL)
  111.   { fprintf(stderr,"Error: Cannot load message font\n");
  112.     exit(1);
  113.    }
  114.  
  115.  
  116.   XSetLineAttributes(display,gc,1,LineSolid,CapButt,JoinMiter);
  117.  
  118.  
  119.   // 16 predefined colors from /usr/lib/X11/rgb.txt
  120.  
  121.   color_count = 0;
  122.  
  123.   new_color("white");          // 0: white
  124.   new_color("black");          // 1: black
  125.   new_color("red");            // 2: red
  126.   new_color("green");          // 3: green
  127.   new_color("blue");           // 4: blue
  128.   new_color("yellow");         // 5: yellow
  129.   new_color("purple");         // 6: violet
  130.   new_color("darkorange");     // 7: orange
  131.   new_color("cyan");           // 8: cyan
  132.   new_color("sienna");         // 9: brown
  133.   new_color("magenta");        //10: pink 
  134.   new_color("forestgreen");    //11: darkgreen
  135.   new_color("cornflowerblue"); //12: darkblue 
  136.   new_color("grey75");         //13: grey1
  137.   new_color("grey60");         //14: grey2
  138.   new_color("grey45");         //15: grey3
  139.  
  140.   gc_val.foreground = color_pix[1];
  141.   gc_val.function  = GXor; 
  142.   gc_val.line_style = LineSolid;
  143.   gc_val.line_width = 1;
  144.   gc_val.font = text_font->fid;
  145.   XChangeGC(display,gc,
  146.             GCForeground|GCFunction|GCLineStyle|GCLineWidth|GCFont,&gc_val);
  147.  
  148.   text_char_width = get_char_width(text_font);
  149.   bold_char_width = get_char_width(bold_font);
  150.   mesg_char_width = get_char_width(mesg_font);
  151.   current_char_width = text_char_width;
  152.   current_font = text_font;
  153. }
  154.  
  155.  
  156. static char* duplicate_string(const char* p)
  157. { char* q = new char[strlen(p)+1];
  158.   strcpy(q,p);
  159.   return q;
  160. }
  161.  
  162. int new_color(const char* name)
  163.   open_display();
  164.  
  165.   // first test if color has been allocated before
  166.  
  167.   for(int i = 0; i < color_count; i++)
  168.      if (strcmp(color_name[i],name)==0) break;
  169.   if (i < color_count) return i;
  170.   
  171.   // if not, try to allocate it
  172.  
  173.   if (color_count == MAX_COLORS) return 0;
  174.  
  175.   XColor xcolor;
  176.  
  177.   if (DefaultDepth(display,screen)==1 && strcmp(name,"white")!=0) 
  178.      XParseColor(display, color_map, "black", &xcolor);
  179.   else
  180.      XParseColor(display, color_map, name, &xcolor);
  181.  
  182.   XAllocColor(display,color_map,&xcolor);
  183.   color_pix[color_count] = xcolor.pixel;
  184.   char* p = new char[strlen(name)+1];
  185.   strcpy(p,name);
  186.   color_name[color_count] = p;
  187.   return color_count++;
  188. }
  189.  
  190.   
  191.  
  192. Window open_window(int x, int y, int width, int height, const char* header,
  193.                                                         const char* label)
  194. {
  195.   Window win;
  196.   XEvent e;
  197.   XSetWindowAttributes attrib;
  198.   XSizeHints size_hints;
  199.   XWMHints wm_hints;
  200.   Pixmap icon_pixmap;
  201.  
  202.   attrib.backing_store = Always;
  203.  
  204.   win= XCreateWindow(display, RootWindow(display, screen), x, y,
  205.                            width,height,2,DefaultDepth(display,screen),
  206.                            InputOutput, DefaultVisual(display,screen), 
  207.                            CWBackingStore, &attrib);
  208.  
  209.   XSelectInput(display,win, KeyPressMask    | PointerMotionMask  | 
  210.                             ButtonPressMask | ButtonReleaseMask  |
  211.                             ExposureMask    | StructureNotifyMask ); 
  212.   
  213.   XSetWindowBackground(display,win, WhitePixel(display, screen)); 
  214.  
  215.   XStoreName(display,win,header);
  216.   XSetIconName(display,win,label);
  217.  
  218.   icon_pixmap = XCreateBitmapFromData(display, win, leda_icon_bits, 
  219.             leda_icon_width, leda_icon_height);
  220.  
  221.   size_hints.flags = PPosition;
  222.   size_hints.x = x;
  223.   size_hints.y = y;
  224.  
  225.   wm_hints.flags = StateHint | IconPixmapHint | InputHint;
  226.   wm_hints.initial_state = NormalState;
  227.   wm_hints.icon_pixmap = icon_pixmap;
  228.   wm_hints.input = True;
  229.   
  230.   XSetWMProperties(display,win,0,0,0,0,&size_hints,&wm_hints,0);
  231.  
  232.   XMapWindow(display,win);
  233.  
  234.   while (1) 
  235.   { XNextEvent(display, &e);
  236.     if (e.type == Expose) break;
  237.    }
  238.  
  239.   XDrawLine(display,win,gc,0,0,width-1,0);
  240.  
  241.   return win;
  242. }
  243.  
  244.  
  245. int display_width(void)
  246. { open_display();
  247.   return DisplayWidth(display,screen);  
  248.  }
  249.  
  250. int display_height(void)
  251. { open_display();
  252.   return DisplayHeight(display,screen); 
  253.  }
  254.  
  255. int display_depth(void)
  256. { open_display();
  257.   return DefaultDepth(display,screen); 
  258.  }
  259.  
  260. void flush_display(void)
  261. { XFlush(display); }
  262.  
  263. void close_display()
  264. { if (display) 
  265.   { XCloseDisplay(display); 
  266.     for(int i=0; i < color_count; i++) delete color_name[i];
  267.     display = 0; 
  268.    } 
  269. }
  270.  
  271. void close_window(Window win)
  272. { XDestroyWindow(display,win); }
  273.  
  274. void clear_window(Window win, int col)
  275. { /* XClearWindow(display,win);  */
  276.   int save_col = set_color(col);
  277.   int save_mode = set_mode(0);
  278.   box(win,1,1,window_width(win)-2,window_height(win)-2);
  279.   set_color(1);
  280.   rectangle(win,0,0,window_width(win)-1,window_height(win)-1);
  281.   set_color(save_col);
  282.   set_mode(save_mode);
  283. }
  284.  
  285.  
  286. void pixel(Window win, int x, int y)
  287. { XDrawPoint(display,win,gc,x,y); }
  288.  
  289.  
  290. void pixels(Window win, int n, int *x, int *y)
  291. { XPoint* points = new XPoint[n];
  292.   int i;
  293.   for(i=0; i<n; i++)
  294.   { points[i].x = (short)x[i];
  295.     points[i].y = (short)y[i];
  296.    }
  297.   XDrawPoints(display,win,gc,points,n,CoordModeOrigin);
  298.   delete points;
  299.  }
  300.  
  301.  
  302. void line(Window win, int x1, int y1, int x2, int y2)
  303. {
  304.    /* problems with clipping coordinates in [i*2^15..(i+1)*2^15-1], i odd  */
  305.  
  306.   if ((x1/(1<<15)) % 2) x1 = -x1;
  307.   if ((x2/(1<<15)) % 2) x2 = -x2;
  308.   if ((y1/(1<<15)) % 2) y1 = -y1;
  309.   if ((y2/(1<<15)) % 2) y2 = -y2;
  310.  
  311.   XDrawLine(display,win,gc,x1,y1,x2,y2); 
  312.  }
  313.  
  314.  
  315. void rectangle(Window win, int x1, int y1, int x2, int y2)
  316. { if (x1 > x2)
  317.   { int x = x1;
  318.     x1 = x2;
  319.     x2 = x;
  320.    }
  321.   if (y1 > y2)
  322.   { int y = y1;
  323.     y1 = y2;
  324.     y2 = y;
  325.    }
  326.   XDrawRectangle(display,win,gc,x1,y1,x2-x1,y2-y1);
  327. }
  328.  
  329.  
  330. void box(Window win, int x1, int y1, int x2, int y2)
  331. { if (x1 > x2)
  332.   { int x = x1;
  333.     x1 = x2;
  334.     x2 = x;
  335.    }
  336.   if (y1 > y2)
  337.   { int y = y1;
  338.     y1 = y2;
  339.     y2 = y;
  340.    }
  341.   XFillRectangle(display,win,gc,x1,y1,x2-x1+1,y2-y1+1);
  342. }
  343.  
  344.  
  345. void arc(Window win, int x0, int y0, int r1, int r2, double start, double angle)
  346. { int s = (int)(360*32*start/M_PI);
  347.   int a = (int)(360*32*angle/M_PI);
  348.   XDrawArc(display,win,gc,x0-r1,y0-r2,2*r1,2*r2,s,a);
  349. }
  350.  
  351.  
  352. void circle(Window win, int x0, int y0, int r)
  353. { XDrawArc(display,win,gc,x0-r,y0-r,2*r,2*r,0,360*64); }
  354.  
  355. void ellipse(Window win, int x0, int y0, int r1, int r2)
  356. { XDrawArc(display,win,gc,x0-r1,y0-r2,2*r1,2*r2,0,360*64); }
  357.  
  358.  
  359. void fill_arc(Window win, int x0, int y0, int r1, int r2, double start, double angle)
  360. { int s = (int)(360*32*start/M_PI);
  361.   int a = (int)(360*32*angle/M_PI);
  362.   XFillArc(display,win,gc,x0-r1,y0-r2,2*r1,2*r2,s,a);
  363. }
  364.  
  365. void fill_circle(Window win, int x0, int y0, int r)
  366. { XFillArc(display,win,gc,x0-r,y0-r,2*r,2*r,0,360*64); }
  367.  
  368.  
  369. void fill_ellipse(Window win, int x0, int y0, int r1, int r2)
  370. { XFillArc(display,win,gc,x0-r1,y0-r2,2*r1,2*r2,0,360*64); }
  371.  
  372.  
  373. void fill_polygon(Window win, int n, int *xcoord, int *ycoord)
  374. { XPoint* edges = new XPoint[n];
  375.   int i;
  376.   for(i=0;i<n;i++) 
  377.   { edges[i].x = (short) xcoord[i];
  378.     edges[i].y = (short) ycoord[i];
  379.    }
  380.  
  381.   XFillPolygon(display,win,gc,edges,n,Nonconvex,CoordModeOrigin);
  382.  
  383.   delete edges;
  384. }
  385.  
  386.  
  387. void put_text(Window win, int x, int y, const char* s, int opaque)
  388. { y += current_font->ascent;
  389.   if (opaque)
  390.      XDrawImageString(display,win,gc,x,y,s,strlen(s));
  391.   else
  392.      XDrawString(display,win,gc,x,y,s,strlen(s));
  393. }
  394.  
  395.  
  396. void put_ctext(Window win, int x, int y, const char* s, int opaque)
  397. { x -= text_width(s)/2;
  398.   y -= text_height(s)/2;
  399.   put_text(win,x,y,s,opaque);
  400.  }
  401.  
  402.  
  403. void show_coordinates(Window win, const char* s)
  404. { put_text(win,window_width(win)-160,2,s,1); }
  405.  
  406.  
  407. int text_width(const char* s)
  408. { return current_char_width * strlen(s); }
  409.  
  410.  
  411. int text_height(const char*)
  412. { return(current_font->ascent+current_font->descent/2); }
  413.  
  414.  
  415. void copy_rect(Window win, int x1, int y1, int x2, int y2, int x, int y)
  416. {
  417.   int save = set_mode(0);   /* src-mode */
  418.  
  419.   Pixmap P=XCreatePixmap(display,win,x2-x1,y2-y1,DefaultDepth(display,screen));
  420.  
  421.   XCopyArea(display,win,P,gc, x1,y1,x2-x1,y2-y1,0,0);
  422.   XCopyArea(display,P,win,gc,0,0,x2-x1,y2-y1,x,y);
  423.  
  424.   set_mode(save);
  425.  }
  426.  
  427. void insert_bitmap(Window win, int width, int height, char* data)
  428. { int save = set_mode(0);
  429.   Pixmap P=XCreatePixmapFromBitmapData(display,win,data,width,height,
  430.                                        BlackPixel(display,screen), 
  431.                                        WhitePixel(display,screen), 
  432.                                        DefaultDepth(display,screen));
  433.   XCopyArea(display,P,win,gc,0,0,width,height,0,0);
  434.   set_mode(save);
  435.  }
  436.  
  437.  
  438. void set_header(Window win, const char* s)
  439. { XStoreName(display,win,s); }
  440.  
  441.  
  442. int set_color(int col)
  443. { int save = COLOR;
  444.   COLOR = col;
  445.   gc_val.foreground = color_pix[col];
  446.   XChangeGC(display,gc,GCForeground,&gc_val);
  447.   return col;
  448.  }
  449.  
  450.  
  451. int set_mode(int m)
  452. { int save = MODE;
  453.  
  454.   MODE = m;
  455.  
  456.   switch (m)  {
  457.  
  458.    case 0 : gc_val.function = GXcopy;
  459.             break;
  460.  
  461.    case 1 : gc_val.function = GXxor;
  462.             break;
  463.  
  464.    case 2 : gc_val.function = GXor;
  465.             break;
  466.  
  467.   }
  468.  
  469.   XChangeGC(display,gc,GCFunction,&gc_val);
  470.  
  471.   return save;
  472. }
  473.  
  474.  
  475. int load_text_font(const char* font_name)
  476. { XFontStruct* fp = XLoadQueryFont(display,font_name);
  477.   if (fp)  
  478.   { text_font = fp;
  479.     text_char_width = get_char_width(fp);
  480.    }
  481.   return (fp != NULL);
  482.  }
  483.  
  484.  
  485. int load_bold_font(const char* font_name)
  486. { XFontStruct* fp = XLoadQueryFont(display,font_name);
  487.   if (fp)  
  488.   { bold_font = fp;
  489.     bold_char_width = get_char_width(fp);
  490.    }
  491.   return (fp != NULL);
  492.  }
  493.  
  494.  
  495. int load_message_font(const char* font_name)
  496. { XFontStruct* fp = XLoadQueryFont(display,font_name);
  497.   if (fp)  
  498.   { mesg_font = fp;
  499.     mesg_char_width = get_char_width(fp);
  500.    }
  501.   return (fp != NULL);
  502.  }
  503.  
  504.  
  505. int set_font(const char *fname)
  506. { XFontStruct* fp = XLoadQueryFont(display,fname);
  507.   if (fp)
  508.   { current_font = fp;
  509.     current_char_width = get_char_width(fp);
  510.     gc_val.font = fp->fid;
  511.     XChangeGC(display,gc,GCFont,&gc_val);
  512.    }
  513.   return (fp != NULL);
  514.  }
  515.  
  516.  
  517. void set_text_font(void)
  518. { current_font = text_font;
  519.   gc_val.font = text_font->fid;
  520.   XChangeGC(display,gc,GCFont,&gc_val);
  521.   current_char_width = text_char_width;
  522.  }
  523.  
  524.  
  525. void set_bold_font(void)
  526. { current_font = bold_font;
  527.   gc_val.font = bold_font->fid;
  528.   XChangeGC(display,gc,GCFont,&gc_val);
  529.   current_char_width = bold_char_width;
  530.  }
  531.  
  532.  
  533. void set_message_font(void)
  534. { current_font = mesg_font;
  535.   gc_val.font = mesg_font->fid;
  536.   XChangeGC(display,gc,GCFont,&gc_val);
  537.   current_char_width = mesg_char_width;
  538.  }
  539.  
  540.  
  541.  
  542. int set_line_width(int w)
  543. { int save = gc_val.line_width;
  544.   gc_val.line_width = w;
  545.   XChangeGC(display,gc,GCLineWidth,&gc_val);
  546.   return save;
  547. }
  548.  
  549.  
  550. int set_line_style(int s)
  551.   int save = LINESTYLE;
  552.  
  553.   LINESTYLE = s;
  554.  
  555.   switch (s)  {
  556.  
  557.    case 0 : gc_val.line_style = LineSolid;
  558.             break;
  559.  
  560.    case 1 : gc_val.line_style = LineOnOffDash;
  561.             XSetDashes(display,gc,0,dash_mask,2);
  562.             break;
  563.  
  564.    case 2 : gc_val.line_style = LineOnOffDash;
  565.             XSetDashes(display,gc,0,dot_mask,2);
  566.             break;
  567.    }
  568.  
  569.   XChangeGC(display,gc,GCLineStyle,&gc_val);
  570.   return save;
  571. }
  572.  
  573.  
  574. void set_read_gc(void)
  575. {XGCValues gc_val0;
  576.  gc_val0.function = GXxor; 
  577.  gc_val0.foreground = BlackPixel(display,screen); 
  578.  gc_val0.line_style = LineSolid;
  579.  gc_val0.line_width = 1;
  580.  XChangeGC(display,gc,GCForeground|GCFunction|GCLineStyle|GCLineWidth,&gc_val0);
  581.  flush_display();
  582. }
  583.  
  584. void reset_gc(void)
  585. { XChangeGC(display,gc,GCForeground|GCFunction|GCLineStyle|GCLineWidth,&gc_val);
  586.   flush_display();
  587. }
  588.  
  589.  
  590. int window_height(Window win)
  591. { Window w;
  592.   int xpos,ypos;
  593.   unsigned width,height,bw,dep;
  594.   XGetGeometry(display,win,&w,&xpos,&ypos,&width,&height,&bw,&dep);
  595.   return height;
  596.  }
  597.  
  598. int window_width(Window win)
  599. { Window w;
  600.   int xpos,ypos;
  601.   unsigned width,height,bw,dep;
  602.   XGetGeometry(display,win,&w,&xpos,&ypos,&width,&height,&bw,&dep);
  603.   return width;
  604.  }
  605.  
  606.  
  607. void window_position(Window win, int *x, int *y)
  608. { XSizeHints size_hints;
  609.   long flags = PPosition;
  610.   XGetWMNormalHints(display,win,&size_hints,&flags);
  611.   *x = size_hints.x;
  612.   *y = size_hints.y;
  613.  }
  614.  
  615.  
  616. static int  handle_event(Window *win,int *val,int *x,int *y,unsigned long *t)
  617. {
  618.   KeySym keysym;
  619.   XComposeStatus status;
  620.  
  621.   int  kind;
  622.   char c;
  623.  
  624.   *win = event.xany.window;
  625.   *val = 0;
  626.  
  627.   switch (event.type) {
  628.  
  629.   case ConfigureNotify: kind = configure_event;
  630.                         *x = event.xconfigure.width;
  631.                         *y = event.xconfigure.height;
  632.                         break;
  633.  
  634.   case DestroyNotify: kind = destroy_event;
  635.                       break;
  636.  
  637.   case ButtonPress: *val = event.xbutton.button;
  638.                     *x = event.xbutton.x;
  639.                     *y = event.xbutton.y;
  640.                     *t = event.xbutton.time;
  641.                     kind = button_press_event;
  642.                     if (event.xbutton.state & Mod1Mask) *val = 2; 
  643.                     if (event.xbutton.state & ShiftMask) *val = -*val;
  644.                     if (event.xbutton.state & ControlMask) *val += 3;
  645.                     break;
  646.  
  647.   case ButtonRelease: *val = event.xbutton.button;
  648.                       *x = event.xbutton.x;
  649.                       *y = event.xbutton.y;
  650.                       *t = event.xbutton.time;
  651.                       if (event.xbutton.state & Mod1Mask) *val = 2; 
  652.                       if (event.xbutton.state & ShiftMask) *val = -*val;
  653.                       if (event.xbutton.state & ControlMask) *val += 3;
  654.                       kind = button_release_event;
  655.                       break;
  656.  
  657.   case MotionNotify: *x = event.xmotion.x;
  658.                      *y = event.xmotion.y;
  659.                      kind = motion_event;
  660.                      break;
  661.  
  662.   case KeyPress: *x = event.xmotion.x;
  663.                  c = 0;
  664.                  XLookupString((XKeyEvent*)&event,&c,1, &keysym, &status);
  665.                  *val = c;
  666.                  kind = key_press_event;
  667.                  break;
  668.  
  669.   }
  670.  
  671.   return kind;
  672. }
  673.  
  674.  
  675. int check_next_event(Window *win, int *val, int *x, int *y, unsigned long *t) 
  676. { // non-blocking 
  677.  
  678.   if (XCheckMaskEvent(display, 
  679.                       KeyPressMask    | // PointerMotionMask  | 
  680.                       ButtonPressMask | ButtonReleaseMask  |
  681.                       ExposureMask    | StructureNotifyMask, &event) == 0) 
  682.       return no_event; 
  683.  
  684.   return handle_event(win,val,x,y,t);
  685. }
  686.  
  687.  
  688. int get_next_event(Window *win, int *val, int *x, int *y, unsigned long *t)
  689. { // blocking
  690.  
  691.   XNextEvent(display, &event);
  692.   return handle_event(win,val,x,y,t);
  693. }
  694.  
  695.  
  696.  
  697. void put_back_event(void)
  698. { XPutBackEvent(display,&event); }
  699.  
  700.